home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / TupleDatabase / BTreeTupleDatabase.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  19.6 KB  |  744 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        BTreeTupleDatabase.cp
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #ifndef __BTREETUPLEDATABASE__
  15. #include "BTreeTupleDatabase.h"
  16. #endif
  17.  
  18. #ifndef    __DEBUGASSERT__
  19. #include "DebugAssert.h"
  20. #endif
  21.  
  22. #ifndef    __DEBUGGINGGEAR__
  23. #include "DebuggingGear.h"
  24. #endif
  25.  
  26. #ifndef __BUFFER__
  27. #include "Buffer.h"
  28. #endif
  29.  
  30. #ifndef    __DATAITEM__
  31. #include "DataItem.h"
  32. #endif
  33.  
  34. #ifndef    __DEBUGCONSTANTS__
  35. #include "DebugConstants.h"
  36. #endif
  37.  
  38. #ifndef    __STDLIB_
  39. #include "StdLib.h"
  40. #endif
  41.  
  42. /***********************************|****************************************/
  43.  
  44. #pragma segment BtreeDatabase
  45.  
  46. /***********************************|****************************************/
  47.  
  48. class TDebugFlag;
  49. extern TDebugFlag chrisFlag;
  50.  
  51. /***********************************|****************************************/
  52.  
  53. const BTreeCompareProc
  54. AKeyDescriptor::GetCompareProc () const
  55. {
  56.     return nil;
  57. }
  58.  
  59. /***********************************|****************************************/
  60.  
  61. ostream&
  62. AKeyDescriptor::operator >> ( ostream& stream ) const
  63. {
  64.     stream << "AKeyDescriptor @ " << (void*) this << '\n';
  65.     stream << "\tGetMaxKeyLength (): " << GetMaxKeyLength () << '\n';
  66.     stream << "\tGetCompareProc (): " << (void*) GetCompareProc () << '\n';
  67.     PrintDescriptor ( stream, GetBtreeDescriptor () );
  68.     return stream;
  69. }
  70.  
  71. /***********************************|****************************************/
  72.  
  73. void
  74. AKeyDescriptor::PrintDescriptor ( ostream& stream, const unsigned char* desc ) const
  75. {
  76.     const unsigned char* stop = desc + *desc;
  77.     stream << "\tlength: " << (short) *desc++ << " bytes";
  78.  
  79.     while ( desc < stop )
  80.     {
  81.         switch ( *desc++ )
  82.         {
  83.             case kdSkip:
  84.                 stream << ", kdSkip";
  85.                 goto dumplen;
  86.  
  87.             case kdByte:
  88.                 stream << ", kdByte";
  89.                 goto dumplen;
  90.  
  91.             case kdWord:
  92.                 stream << ", kdWord";
  93.                 goto dumplen;
  94.  
  95.             case kdLong:
  96.                 stream << ", kdLong";
  97.                 goto dumplen;
  98.  
  99.             case kdSignedByte:
  100.                 stream << ", kdSignedByte";
  101.                 goto dumplen;
  102.  
  103.             case kdSignedWord:
  104.                 stream << ", kdSignedWord";
  105.                 goto dumplen;
  106.  
  107.             case kdSignedLong:
  108.                 stream << ", kdSignedLong";
  109.                 goto dumplen;
  110.  
  111.             case kdString:
  112.                 stream << ", kdString, (" << (short) *desc++ << ')';
  113.                 goto dumpcase;
  114.  
  115.             case kdFLString:
  116.                 stream << ", kdFLString, (" << (short) *desc++ << ')';
  117.                 goto dumpcase;
  118.  
  119.             case kdDTString:
  120.                 stream << ", kdDTString\n";
  121.                 break;
  122.  
  123.             case kdUseKCProc:
  124.                 stream << ", kdUseKCProc\n";
  125.                 break;
  126.  
  127. dumplen:        stream << " (" << (short) *desc++ << ')';
  128.                 break;
  129.  
  130. dumpcase:        if ( *desc & caseSens )
  131.                     stream << ", case sensitive:";
  132.                 else
  133.                     stream << ", case insensitive:";
  134.  
  135.                 if ( *desc & diacNsens )
  136.                     stream << "diacrit insensitive";
  137.                 else
  138.                     stream << "diacrit sensitive";
  139.                 desc++;
  140.                 break;
  141.  
  142.             default:
  143.                 stream << ", ???";
  144.                 break;
  145.         }
  146.     }
  147. }
  148.  
  149. /***********************************|****************************************/
  150.  
  151. class CStringDescriptor : public AKeyDescriptor
  152. {
  153. public:        CStringDescriptor ( Boolean caseSensitive = true, Boolean diacritSensitive = false );
  154.     virtual    ~CStringDescriptor ();
  155.     virtual    const unsigned char*    GetBtreeDescriptor () const;
  156.  
  157. private:    unsigned char            fCaseFlag, fDiacritFlag;
  158. };
  159.  
  160. /***********************************|****************************************/
  161.  
  162. class CProcedureDescriptor : public AKeyDescriptor
  163. {
  164. public:
  165.             CProcedureDescriptor ();
  166.     virtual    ~CProcedureDescriptor ();
  167.     virtual    const unsigned char*    GetBtreeDescriptor () const;
  168.     virtual    const BTreeCompareProc    GetCompareProc () const;     
  169.  
  170. private:
  171.     static    short                     CompareProc ();
  172. };
  173.  
  174. /***********************************|****************************************/
  175.  
  176. class TBTreeKeyWrapper : public CPrefixDataItem
  177. {
  178. public:        TBTreeKeyWrapper ( const ATupleKey& );
  179.     virtual    ~TBTreeKeyWrapper ();
  180. };
  181.  
  182. /***********************************|****************************************/
  183.  
  184. class TBTreeDataWrapper : public CPrefixDataItem
  185. {
  186. public:        TBTreeDataWrapper ( ADataItem&, Boolean updateSource );
  187.             TBTreeDataWrapper ( ADataItem&, unsigned long initialSize );
  188.     virtual    ~TBTreeDataWrapper ();
  189. };
  190.  
  191. /***********************************|****************************************/
  192. /***********************************|****************************************/
  193.  
  194. inline
  195. TBTreeKeyWrapper::~TBTreeKeyWrapper ()
  196. {
  197. }
  198.  
  199. /***********************************|****************************************/
  200. /***********************************|****************************************/
  201.  
  202. inline
  203. TBTreeDataWrapper::~TBTreeDataWrapper ()
  204. {
  205. }
  206.  
  207. /***********************************|****************************************/
  208. /***********************************|****************************************/
  209.  
  210. inline OSErr
  211. TBTreeDatabase::GetError () const
  212. {
  213.     return fError;
  214. }
  215.  
  216. /***********************************|****************************************/
  217. /***********************************|****************************************/
  218.  
  219. CStringDescriptor::CStringDescriptor ( Boolean paramCaseSensitive, Boolean paramDiacritSensitive ):
  220.     AKeyDescriptor (),
  221.     fCaseFlag ( paramCaseSensitive ? caseSens : 0 ),
  222.     fDiacritFlag ( paramDiacritSensitive ? 0 : diacNsens )
  223. {
  224. }
  225.  
  226. CStringDescriptor::~CStringDescriptor ()
  227. {
  228. }
  229.  
  230. const unsigned char*
  231. CStringDescriptor::GetBtreeDescriptor () const
  232. {
  233.     static unsigned char kDescriptor [ 4 ] = { 3, kdString, 1, 0 };
  234. //     kDescriptor [ 3 ] = fCaseFlag | fDiacritFlag;
  235.     return kDescriptor;
  236. }
  237.  
  238. /***********************************|****************************************/
  239. /***********************************|****************************************/
  240.  
  241. CProcedureDescriptor::CProcedureDescriptor ():
  242.     AKeyDescriptor ()
  243. {
  244. }
  245.  
  246. CProcedureDescriptor::~CProcedureDescriptor ()
  247. {
  248. }
  249.  
  250. const unsigned char*
  251. CProcedureDescriptor::GetBtreeDescriptor () const
  252. {
  253.     static const unsigned char kDescriptor [] = { 2, kdUseKCProc };
  254.     return kDescriptor;
  255. }
  256.  
  257. const BTreeCompareProc
  258. CProcedureDescriptor::GetCompareProc () const
  259. {
  260.     return CompareProc;
  261. }
  262.  
  263. const void* GetA1() = { 0x2009 };
  264. const void*    GetA0() = { 0x2008 };
  265.  
  266. short
  267. CProcedureDescriptor::CompareProc ()
  268. {
  269.     NOT_IMPLEMENTED ();
  270.     return 0;
  271. }
  272.  
  273. /***********************************|****************************************/
  274.  
  275. static const CProcedureDescriptor kProcedureDescriptor;
  276. const AKeyDescriptor& AKeyDescriptor::kCompareProc = kProcedureDescriptor;
  277.  
  278. static const CStringDescriptor kStringDescriptor;
  279. const AKeyDescriptor& AKeyDescriptor::kString = kStringDescriptor;
  280.  
  281. /***********************************|****************************************/
  282. /***********************************|****************************************/
  283.  
  284. TBTreeKeyWrapper::TBTreeKeyWrapper ( const ATupleKey& key ):
  285.     CPrefixDataItem ( key.GetData (), key.GetLength (), CPrefixDataItem::kByte )
  286. {
  287. }
  288.  
  289. /***********************************|****************************************/
  290. /***********************************|****************************************/
  291.  
  292. TBTreeDataWrapper::TBTreeDataWrapper ( ADataItem& buffer, Boolean update ):
  293.     CPrefixDataItem ( buffer, update, CPrefixDataItem::kWord )
  294. {
  295. }
  296.  
  297. /***********************************|****************************************/
  298.  
  299. TBTreeDataWrapper::TBTreeDataWrapper ( ADataItem& buffer, unsigned long logicalLength ):
  300.     CPrefixDataItem ( CPrefixDataItem::kWord, logicalLength )
  301. {
  302.     CPrefixDataItem::SetSource ( &buffer );
  303.     CPrefixDataItem::SetUpdate ( true );
  304. }
  305.  
  306. /***********************************|****************************************/
  307. /***********************************|****************************************/
  308.  
  309. TBTreeDatabase::TBTreeDatabase ( const TFileSpec& spec, const AKeyDescriptor& descriptor, Mode mode, Rights rights ):
  310.     ATupleDatabase (),
  311.     fFile ( spec ),
  312.     fError ( noErr ),
  313.     fRights ( rights )
  314. {
  315.     ::memset ( &fParam, 0, sizeof ( fParam ) );
  316.  
  317.     if ( mode == kReadWriteNew )
  318.     {
  319.         ASSERT_RETURN ( fFile.CreateFile ( 'MPS ', 'b*tr' ) );
  320.  
  321.         BTParam tParam;
  322.         tParam.ioCompletion = nil;
  323.         tParam.ioNamePtr = fFile.GetPName ();
  324.         tParam.ioVRefNum = fFile.GetVolume ();
  325.         tParam.ioDirID = fFile.GetParent ();
  326.         tParam.ioBTClumpSize = 0;
  327.         tParam.ioBTMaxKLen = (short) descriptor.GetMaxKeyLength ();
  328.         tParam.ioBTKDPtr = (Ptr) descriptor.GetBtreeDescriptor ();
  329.  
  330.         ASSERT_RETURN ( HandleError ( BTInit ( &tParam, false ) ) );
  331.     }
  332.  
  333.     fParam.ioVRefNum = fFile.GetVolume ();
  334.     fParam.ioDirID = fFile.GetParent ();
  335.     fParam.ioNamePtr = fFile.GetPName ();
  336.     fParam.ioPermssn = mode == kReadOnly ? fsRdPerm : fsRdWrPerm;
  337.     fParam.ioBTKCProc = (Ptr) descriptor.GetCompareProc ();
  338.     fParam.ioBTRsrvUID = (long) this;
  339.  
  340.     ASSERT_RETURN ( HandleError ( BTOpen ( &fParam, false ) ) );
  341.  
  342.     if ( fRights == kExclusive )
  343.         if ( ReserveAccess () == false )
  344.         {
  345.             fRights = kNonExclusive;
  346.             fParam.ioBTRsrvUID = 0;
  347.         }
  348.  }
  349.  
  350. /***********************************|****************************************/
  351.  
  352. TBTreeDatabase::~TBTreeDatabase ( void )
  353. {
  354.     if ( fParam.ioRefNum != 0 )
  355.     {
  356.         if ( fRights == kExclusive )
  357.             ReleaseAccess ();
  358.  
  359.         ASSERT ( HandleError ( BTClose ( &fParam, false ) ) );
  360.         fParam.ioRefNum = 0;
  361.     }
  362. }
  363.  
  364. /***********************************|****************************************/
  365.  
  366. Boolean
  367. TBTreeDatabase::SetTuple ( const ATupleKey& key, const ADataItem& data )
  368. {
  369.     TBTreeKeyWrapper keyWrapper ( key );
  370.     TBTreeDataWrapper dataWrapper ( (ADataItem&) data, false );
  371.     unsigned long dataLength = dataWrapper.GetPhysicalLength ();
  372.  
  373.     fParam.ioBTKeyPtr = (Ptr) keyWrapper.GetPhysicalStart ();
  374.     fParam.ioBuffer = (Ptr) dataWrapper.GetPhysicalStart ();
  375.     fParam.ioReqCount = dataLength;
  376.  
  377.     ASSERT_RETURN_ZERO ( HandleError ( BTSetRec ( &fParam, false ) ) );
  378.     ASSERT_RETURN_ZERO ( dataLength == fParam.ioActCount );
  379.  
  380.     return true;
  381. }
  382.  
  383. /***********************************|****************************************/
  384.  
  385. Boolean
  386. TBTreeDatabase::SetTuple ( unsigned long index, const ADataItem& data )
  387. {
  388.     ATupleKey* key = CreateKey ( index );
  389.     ASSERT_RETURN_ZERO ( key != nil );
  390.     Boolean result = ASSERT ( SetTuple ( *key, data ) );
  391.     delete key;
  392.     return result;
  393. }
  394.  
  395. /***********************************|****************************************/
  396.  
  397. Boolean
  398. TBTreeDatabase::GetTupleData ( unsigned long index, ADataItem& data )
  399. {
  400.     ATupleKey* key = CreateKey ( index );
  401.  
  402.     if ( key == nil )
  403.         return false;
  404.  
  405.     Boolean result = GetTupleData ( *key, data );
  406.  
  407.     delete key;
  408.     return result;
  409. }
  410.  
  411. /***********************************|****************************************/
  412.  
  413. Boolean
  414. TBTreeDatabase::GetTupleData ( const ATupleKey& key, ADataItem& data )
  415. {
  416.     TBTreeKeyWrapper keyWrapper ( key );
  417.  
  418.     unsigned long newDataSize = GetTupleDataSize ( keyWrapper );
  419.  
  420.     if ( newDataSize == 0 )
  421.         return false;
  422.  
  423.     TBTreeDataWrapper dataWrapper ( data, newDataSize );
  424.  
  425.     fParam.ioBTKeyPtr = (Ptr) keyWrapper.GetPhysicalStart ();
  426.     fParam.ioBuffer = (Ptr) dataWrapper.GetPhysicalStart ();
  427.     fParam.ioReqCount = dataWrapper.GetPhysicalLength ();
  428.  
  429.     return HandleError ( BTSearch ( &fParam, false ) );
  430. }
  431.  
  432. /***********************************|****************************************/
  433.  
  434. Boolean
  435. TBTreeDatabase::GetTuple ( unsigned long index, ATupleKey& key, ADataItem& data )
  436. {
  437.     if ( !GetTupleKey ( index, key ) )
  438.         return false;
  439.     return GetTupleData ( key, data );
  440. }
  441.  
  442. /***********************************|****************************************/
  443.  
  444. Boolean
  445. TBTreeDatabase::DoesTupleExist ( const ATupleKey& key ) const
  446. {
  447.     unsigned long length = 0;
  448.     return ((TBTreeDatabase*) this )->GetTupleDataSize ( key, length ) == true;
  449. }
  450.  
  451. /***********************************|****************************************/
  452.  
  453. Boolean
  454. TBTreeDatabase::GetTupleKey ( unsigned long index, ATupleKey& key )
  455. {
  456.     CTupleKey* newKey = CreateKey ( index );
  457.  
  458.     if ( newKey )
  459.     {
  460.         key = *newKey;
  461.         delete newKey;
  462.         return true;
  463.     }
  464.     else
  465.         return false;
  466. }
  467.  
  468. /***********************************|****************************************/
  469.  
  470. CTupleKey*
  471. TBTreeDatabase::CreateKey ( unsigned long index )
  472. {
  473.     const unsigned long kKeyLength = MaxKeyLen;
  474.     unsigned char keyBuffer [ kKeyLength + 1 ];
  475.     fParam.ioBTKeyPtr = (Ptr) keyBuffer;
  476.     fParam.ioKReqCount = (short) kKeyLength;
  477.  
  478.     short bufferLength = 0;
  479.     fParam.ioBuffer = (Ptr) &bufferLength;
  480.     fParam.ioReqCount = sizeof ( bufferLength );
  481.     fParam.ioBTPosMode = (short) index - 1;
  482.     InvalidateHint ();
  483.  
  484.      if ( !HandleError ( BTGetRec ( &fParam, false ) ) )
  485.         return nil;
  486.  
  487. #if debug
  488.     ASSERT_RETURN_ZERO ( fParam.ioKActCount == keyBuffer [ 0 ] + 1 );
  489. #endif
  490.  
  491.     return new CTupleKey ( keyBuffer + 1, keyBuffer [ 0 ] );
  492. }
  493.  
  494. /***********************************|****************************************/
  495.  
  496. Boolean
  497. TBTreeDatabase::GetTupleDataSize ( const ATupleKey& key, unsigned long& dataLength )
  498. {
  499.     dataLength = GetTupleDataSize ( TBTreeKeyWrapper ( key ) );
  500.     return dataLength > 0;
  501. }
  502.  
  503. /***********************************|****************************************/
  504.  
  505. unsigned long
  506. TBTreeDatabase::GetTupleDataSize ( const TBTreeKeyWrapper& key )
  507. {
  508.     short datADataItem = 0;
  509.     fParam.ioBuffer = (Ptr) &datADataItem;
  510.     fParam.ioReqCount = sizeof ( datADataItem );
  511.     fParam.ioBTKeyPtr = (Ptr) key.GetPhysicalStart ();
  512.     return HandleError ( BTSearch ( &fParam, false ) ) ? datADataItem : 0;
  513. }
  514.  
  515. /***********************************|****************************************/
  516.  
  517. Boolean
  518. TBTreeDatabase::FindIndexOfTuple ( const ATupleKey& key, unsigned long& index )  const
  519. {
  520.     TBTreeKeyWrapper keyWrapper ( key );
  521.     ((TBTreeDatabase*) this)->fParam.ioBTKeyPtr = (Ptr) keyWrapper.GetPhysicalStart ();
  522.     ((TBTreeDatabase*) this)->fParam.ioBuffer = nil;
  523.     ((TBTreeDatabase*) this)->fParam.ioReqCount = 0;
  524.     ((TBTreeDatabase*) this)->fParam.ioKReqCount = 1;
  525.     ((TBTreeDatabase*) this)->fParam.ioBTPosMode = 0;
  526.     ((TBTreeDatabase*) this)->InvalidateHint ();
  527.  
  528.     if ( !HandleError ( BTSearch ( &((TBTreeDatabase*)this)->fParam, false ) ) )
  529.         return false;
  530.  
  531.     index = (unsigned long) fParam.ioBTHint3 + 1;
  532.     return true;
  533. }
  534.  
  535. /***********************************|****************************************/
  536.  
  537. Boolean
  538. TBTreeDatabase::DeleteTuple ( const ATupleKey& key )
  539. {
  540.     TBTreeKeyWrapper keyWrapper ( key );
  541.     fParam.ioBTKeyPtr = (Ptr) keyWrapper.GetPhysicalStart ();
  542.  
  543.     if ( !HandleError ( BTDelete ( &fParam, false ) ) )
  544.         return false;
  545.  
  546.     return true;
  547. }
  548.  
  549. /***********************************|****************************************/
  550.  
  551. unsigned long
  552. TBTreeDatabase::CountTuples () const
  553. {
  554.     BTParam tParam;
  555.     return GetInfo ( tParam ) ? tParam.ioBTRecNum : 0;
  556. }
  557.  
  558. /***********************************|****************************************/
  559.  
  560. Boolean
  561. TBTreeDatabase::GetInfo ( BTParam& tParam ) const
  562. {
  563.     tParam.ioCompletion = nil;
  564.     tParam.ioRefNum = fParam.ioRefNum;
  565.     tParam.ioBTKDPtr = nil;
  566.     tParam.ioBTKDReqCount = 0;
  567.     return HandleError ( BTGetInfo ( &tParam, false ) );
  568. }
  569.  
  570. /***********************************|****************************************/
  571.  
  572. void
  573. TBTreeDatabase::InvalidateHint ()
  574. {
  575.     fParam.ioBTHint1 = 0;
  576.     fParam.ioBTHint2 = 0;
  577.     fParam.ioBTHint3 = 0;
  578. }
  579.  
  580. /***********************************|****************************************/
  581.  
  582. void
  583. TBTreeDatabase::Flush ()
  584. {
  585.     fParam.ioBTWriteFlag = true;
  586.     ASSERT ( HandleError ( BTFlush ( &fParam, false ) ) );
  587. }
  588.  
  589. /***********************************|****************************************/
  590.  
  591. extern ostream& DumpHex (ostream& s, const void *p, unsigned long size);
  592.  
  593. void
  594. Print ( ostream& stream, const BTIOParam& fParam )
  595. {
  596.     stream << "\tioBuffer: ";
  597.     if ( fParam.ioBuffer )
  598.         DumpHex ( stream, (char*) fParam.ioBuffer, fParam.ioReqCount );
  599.     else
  600.         stream << "<NIL>\n";
  601.     stream << "\tioCompletion: " << fParam.ioCompletion << '\n';
  602.     stream << "\tioResult: " << fParam.ioResult << '\n';
  603.     stream << "\tioNamePtr:" << (StringPtr) fParam.ioNamePtr << '\n';
  604.     stream << "\tioVRefNum: " << fParam.ioVRefNum << '\n';
  605.     stream << "\tioRefNum: " << fParam.ioRefNum << '\n';
  606.     stream << "\tioBTWriteFlag: " << hexo << fParam.ioBTWriteFlag << dec << '\n';
  607.     stream << "\tioPermssn: " << (short) fParam.ioPermssn << '\n';
  608.     stream << "\tioMisc: " << (void*) fParam.ioMisc << '\n';
  609.     stream << "\tioReqCount: " << fParam.ioReqCount << '\n';
  610.     stream << "\tioActCount: " << fParam.ioActCount << '\n';
  611.     stream << "\tioBTKeyPtr: ";
  612.     if ( fParam.ioBTKeyPtr )
  613.         DumpHex ( stream, (char*) fParam.ioBTKeyPtr, fParam.ioBTKeyPtr [ 0 ] + 1 );
  614.     else
  615.         stream << "<NIL>\n";
  616.     stream << "\tioDirID: " << fParam.ioDirID << '\n';
  617.     stream << "\tioBTHint1: " << fParam.ioBTHint1 << '\n';
  618.     stream << "\tioBTHint2: " << fParam.ioBTHint2 << '\n';
  619.     stream << "\tioBTHint3: " << fParam.ioBTHint3 << '\n';
  620.     stream << "\tioBTHint4: " << fParam.ioBTHint4 << '\n';
  621.     stream << "\tioBTHint5: " << fParam.ioBTHint5 << '\n';
  622.     stream << "\tioBTPosMode: " << fParam.ioBTPosMode << '\n';
  623.     stream << "\tioKReqCount: " << fParam.ioKReqCount << '\n';
  624.     stream << "\tioKActCount: " << fParam.ioKActCount << '\n';
  625.     stream << "\tioBTRsrvUID: " << fParam.ioBTRsrvUID << '\n';
  626.     stream << "\tioBTDataSize: " << fParam.ioBTDataSize << '\n';
  627.     stream << "\tioBTKCProc: " << (void*) fParam.ioBTKCProc << '\n';
  628.     stream.flush ();
  629. }
  630.  
  631. /***********************************|****************************************/
  632.  
  633. ostream&
  634. TBTreeDatabase::operator >> ( ostream& stream ) const
  635. {
  636.     Boolean flag = chrisFlag.Flag ( kExtensiveTupleDBDescribe );
  637.     Boolean flag2 = chrisFlag.Flag ( kBTreeErrorDescribe );
  638.     chrisFlag.SetFlag ( kExtensiveTupleDBDescribe, false );
  639.     chrisFlag.SetFlag ( kBTreeErrorDescribe, false );
  640.  
  641.     ATupleDatabase::operator >> ( stream );
  642.     stream << "TBTreeDatabase @ " << (void*) this << '\n';
  643.  
  644.     if ( flag )
  645.     {
  646.         stream << fFile << endl;
  647.         stream << "\tfError: \"" << GetErrorName ( fParam.ioResult ) << "\"\n";
  648.         Print ( stream, fParam );
  649.     }
  650.  
  651.     chrisFlag.SetFlag ( kExtensiveTupleDBDescribe, flag );
  652.     chrisFlag.SetFlag ( kBTreeErrorDescribe, flag2 );
  653.  
  654.     return stream;
  655. }
  656.  
  657. /***********************************|****************************************/
  658.  
  659. Boolean
  660. TBTreeDatabase::HandleError ( OSErr error ) const
  661. {
  662.     ( (TBTreeDatabase*) this )->fError = error;
  663. //     ( (TBTreeDatabase*) this )->fParam.ioResult = error;
  664.  
  665. #if debug
  666.     if ( ( fError != noErr ) && chrisFlag.Flag ( kBTreeErrorDescribe ) )
  667.     {
  668.         Boolean prevFlag = chrisFlag.Flag ( kExtensiveTupleDBDescribe );
  669.         chrisFlag.SetFlag ( kExtensiveTupleDBDescribe, true );
  670.         chris << "\n\n######### ERROR ########\n" << *this << '\n';
  671.         chrisFlag.SetFlag ( kExtensiveTupleDBDescribe, prevFlag );
  672.     }
  673. #endif
  674.  
  675.     return fError == noErr;
  676. }
  677.  
  678. /***********************************|****************************************/
  679.  
  680. Boolean
  681. TBTreeDatabase::DeleteDatabase ()
  682. {
  683.     if ( fParam.ioRefNum != 0 )
  684.     {
  685.         ASSERT_RETURN_ZERO ( HandleError ( BTClose ( &fParam, false ) ) );
  686.         fParam.ioRefNum = 0;
  687.     }
  688.  
  689.     ASSERT_RETURN_ZERO ( fFile.DeleteFile () );
  690.     return true;
  691. }
  692.  
  693. /***********************************|****************************************/
  694.  
  695. Boolean
  696. TBTreeDatabase::ReserveAccess ()
  697. {
  698.     ASSERT_RETURN_ZERO ( HandleError ( BTRsrvAccess ( &fParam, false ) ) );
  699.     return true;
  700. }
  701.  
  702. /***********************************|****************************************/
  703.  
  704. Boolean
  705. TBTreeDatabase::ReleaseAccess ()
  706. {
  707.     ASSERT_RETURN_ZERO ( HandleError ( BTRelAccess ( &fParam, false ) ) );
  708.     return true;
  709. }
  710.  
  711. /***********************************|****************************************/
  712.  
  713. extern const char* GetErrorName ( OSErr );
  714.  
  715. const char*
  716. TBTreeDatabase::GetErrorName ( OSErr error )
  717. {
  718.     switch ( error )
  719.     {
  720.         case notBTree: return "notBTree";
  721.         case btBadNode: return "btBadNode";
  722.         case btSizeErr: return "btSizeErr";
  723.         case btNoSpace: return "btNoSpace";
  724.         case btDupRecErr: return "btDupRecErr";
  725.         case btRecNotFnd: return "btRecNotFnd";
  726.         case btKeyLenErr: return "btKeyLenErr";
  727.         case btKeyAttrErr: return "btKeyAttrErr";
  728.         case btKeyFdErr: return "btKeyFdErr";
  729.         case btPMInvalid: return "btPMInvalid";
  730.         case btKDLenErr: return "btKDLenErr";
  731.         case btKDTypeErr: return "btKDTypeErr";
  732.         case btBadUIDErr: return "btBadUIDErr";
  733.         case btNoKDErr: return "btNoKDErr";
  734.         case btDepthErr: return "btDepthErr";
  735.         case btNoKCProcErr: return "btNoKCProcErr";
  736.         case btVersionErr: return "btVersionErr";
  737.         case btEofErr: return "btEofErr";
  738.         case btBofErr: return "btBofErr";
  739.         default: return ::GetErrorName ( error );
  740.     }
  741. }
  742.  
  743. /***********************************|****************************************/
  744.